<?php

/**
 * ecshop ERP v1.0
 * ----------------------------------------------------------------------------
 * http://www.phpally.com
 * Jacklee的博客 致力于php技术
 * ----------------------------------------------------------------------------
 * 作者: Jacklee
 * 邮箱: jack349392900@gmail.com
 * 创建时间: 2013-11-18
 * 最后修改时间: 2013-11-18
 */

/**
 * CSV处理类
 * 
 * decode使用方法：
 * $file_handle=fopen($souce_file,'r');//打开文件
 * $contents = fread($file_handle, filesize($souce_file));//读取文件信息
 * $contents = iconv('gbk','utf-8',$contents);//编码转换
 * $csv=new cls_csv();
 * $result=$csv->decode($contents);
 * 
 * encode使用方法：
 * $csv=new cls_csv();
   $array=array(
	'0'=> array(
		'1',
		'2',
		'3',
	),
	'1'=>	array(
		'0'=>'1',
		'1'=>'2',
		'2'=>'3',	
	),
	'2'=> array(
		'0'=>'1',
		'1'=>'2',
		'2'=>'3',
	),
	);
 * $result=$csv->encode($array);
 */

require_once(dirname(__FILE__) . '/cls_base.php');

class cls_csv extends cls_base{
	
	private $str_coding='utf-8';

	public function cls_csv($str_coding='utf-8')
	{
		$this->str_coding=$str_coding;
	}
	
	//public function __construct($str_coding='utf-8')
	//{
	//	$this->cls_csv($str_coding);
	//}
	
	
	/**
	 * 去除字符串头部和尾部的双引号
	 */
	private function trim_quote($str)
	{
		if($this->get_substr($str,0,1)=='"')
		{
			$str=$this->get_substr($str,1,$this->get_strlen($str)-1);
		}
		
		if($this->get_substr($str,-1,1)=='"')
		{
			$str=$this->get_substr($str,0,$this->get_strlen($str)-1);
		}	
		
		return $str;	
	}
	/**
	 * 获取字符串里双引号的个数
	 * @param object $str
	 * @return 
	 */
	private function get_quote_number($str)
	{
		$k=0;
		for($i=0;$i<=$this->get_strlen($str)-1;$i++)
		{
			if($this->get_substr($str,$i,1)=='"')
			{
				$k++;
			}
		}
		return $k;
	}
	
	/**
	 * 是否是偶数
	 * @param object $num
	 * @return 
	 */
	private function is_even($num)
	{
		if($num%2==0)
		{
			return true;
		}
		else{
			return false;
		}	
	}
	/**
	 * 对双引号进行反转义,例如 '""""',返回'"""'
	 * @param object $str
	 * @return 
	 */
	private function trim_dbl_quote($str)
	{
		$has_beginning_quote=0;
		$has_endding_quote=0;
		
		if($this->get_substr($str,0,1)=='"')
		{
			$str=$this->get_substr($str,1,$this->get_strlen($str)-1);
			$has_beginning_quote=1;
		}		
		
		if($this->get_substr($str,-1,1)=='"')
		{
			$str=$this->get_substr($str,0,$this->get_strlen($str)-1);
			$has_endding_quote=1;
		}		
		
		$str=preg_replace('/""/','"',$str);	
		
		if($has_beginning_quote==1)
		{
			$str='"'.$str;
		}
		
		if($has_endding_quote==1)
		{
			$str=$str.'"';
		}	
		
		return 	$str;	
	}		
	
	/**
	 * 对csv字符串进行一次分割，例如'"1",2,3'，返回array(0=>'"1"',1=>'2,3');
	 * @param object $str
	 * @return 
	 */
	private function explode_csv_row($str)
	{	
			if(empty($str))
			{
				return array();
			}
			
			$first_char=$this->get_substr($str,0,1);
			if($first_char==',')//如果首字符是逗号
			{
				$result[]='';
				$result[]=$this->get_substr($str,1,$this->get_strlen($str)-1);
			}
			elseif($first_char=='"')//如果首字符是双引号
			{
				for($i=1;$i<=$this->get_strlen($str)-1;$i++)//从第二个字符开始核对
				{
					if($this->get_substr($str,$i,1)=='"')
					{	//核对后一个字符
						$next_char=$this->get_substr($str,$i+1,1);
						
						if($next_char==',')//如果后一个是逗号
						{
							$quote_number=$this->get_quote_number($this->get_substr($str,0,$i+1));
							if($this->is_even($quote_number))//偶数
							{
								$result[0]=$this->get_substr($str,0,$i+1);
								
								$result[1]=$this->get_substr($str,$i+2,$this->get_strlen($str)-$i-2);

								break;
							}
							else{
								continue;
							}
						}
						else{
							continue;
						}
					}
					else{
						continue;
					}					
				}
			}
			else{
					$comma_pos=$this->get_strpos($str,',');
					if($comma_pos==false)//无逗号
					{
						$result[0]=$str;
					}
					else{
						$result[0]=$this->get_substr($str,0,$this->get_strpos($str,','));
						$result[1]=$this->get_substr($str,$this->get_strpos($str,',')+1,$this->get_strlen($str)-$this->get_strpos($str,',')-1);							
					}
			}
			
			if((empty($result) || (empty($result[0]) && empty($result[1])))&& $str!=',')
			{
					$result[0]=$str;
				}

			return $result;
	}	
	
	/**
	 * 对csv字符串进行递规分割，并去除首尾双引号和对双引号进行反转义
	 * @param object $str
	 * @return 
	 */
	private function explode_csv($str)
	{
		if(!is_array($str))
		{
			$str=$this->explode_csv_row($str);
		}

		if(empty($str))
		{
			return array();
		}
		else{
				$count=count($str);
				
				$last_item=$str[$count-1];
				
				$explode_result=$this->explode_csv_row($last_item);
	
				if(!empty($explode_result) && count($explode_result)==2)
				{
							$str[$count-1]=$explode_result[0];
							$str[$count]=$explode_result[1];	
							$str=$this->explode_csv($str);						
				}		
		}	
	  
	  
	  if(!empty($str))
	  {
	  	foreach($str as $key => $item)
	  	{
	  		$str[$key]=$this->trim_quote($this->trim_dbl_quote($item));
	  	}
	  }
	  
	return $str;
	}
	
	public function decode($csv_stream)
	{
		//把回车字符替换为'|'
		$csv_stream=preg_replace("/([\r\n]+)/",'|',$csv_stream);
		$csv_stream_array=explode('|',$csv_stream);
		
		//return $csv_stream_array;
		
		if(!empty($csv_stream_array))
		{
			foreach($csv_stream_array as $key=> $row)
			{
				if(!empty($row))
				{
					$result_array[]=$this->explode_csv($row);
				}
			}
		}
		
		return $result_array;
	}
	
	

	/**
	 * 字符串头部和尾部加双引号
	 */
	private function add_quote($str)
	{
		return '"'.$str.'"';	
	}
	

	/**
	 * 对双引号进行转义,例如 '"',返回'""'
	 * @param object $str
	 * @return 
	 */
	private function add_dbl_quote($str)
	{
		$str=preg_replace('/"/','""',$str);	
		return 	$str;	
	}		

	public function encode($csv_array)
	{
		$str="";
		if(!empty($csv_array))
		{
			foreach($csv_array as $key=>$row)
			{
				if(is_array($row) && !empty($row))
				{
					$new_row=array();
					
					foreach($row as $k=>$v)
					{
						$new_row[]=$v;
					}
				
					$count=count($row);
					
					foreach($new_row as $k=>$v)
					{
						$str.=$this->add_quote($this->add_dbl_quote($v));
						
						if($k!=$count-1)
						{
							$str.=",";
						}
					}
				}
				$str.="\r\n";
			}
		}
		
		return $str;
	}	
	
}

?>